﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Dimok;

namespace Dimok.Web.UI {

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>	Extentions. </summary>
	///
	/// <remarks>	Dimon, 12/21/2010. </remarks>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	static public class Extentions {

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A Control extension method that registers the css. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="control">	The control to act on. </param>
		/// <param name="CssName">	Name of the css. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void RegisterCSS(this Control control, string CssName) {
			HtmlLink cssLink = new HtmlLink();
			cssLink.Href = CssName;
			cssLink.Attributes.Add("type", "text/css");
			cssLink.Attributes.Add("rel", "stylesheet");
			if( control.Page != null && control.Page.Header != null)
				control.Page.Header.Controls.Add(cssLink);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	An object extension method that converts an o to a data object. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="o">	The o to act on. </param>
		///
		/// <returns>	This object as an object. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static object ToDataObject(this object o) {
			var d = o.GetType().GetProperties().Select(s => new DynamicProperty( s.Name, s.PropertyType)); 
			Type t = DynamicExpression.CreateClass(d.ToArray());
			object ret = Activator.CreateInstance(t);
			foreach (var e in d)
				ret.SetProperty(e.Name, o.GetProperty(e.Name));
			return ret;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A HtmlControl extension method that sets a profile identifier. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="control">	The control to act on. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void SetProfileID(this HtmlControl control) {
			control.Attributes["profileID"] = control.ID;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A Control extension method that script local get. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="control">	The control to act on. </param>
		/// <param name="sender">		Source of the event. </param>
		/// <param name="e">				Event information. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void ScriptLocalGet(this Control control, object sender, EventArgs e) {
			JS.ScriptGet(sender as Control);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A Control extension method that script local get. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="control">	The control to act on. </param>
		/// <param name="sender">		Source of the event. </param>
		/// <param name="e">				Event information. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void ScriptLocalGet(this UserControl control, object sender, EventArgs e) {
			JS.ScriptGet(sender as Control);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A UserControl extension method that script local find. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="control">	The control to act on. </param>
		/// <param name="sender">		Source of the event. </param>
		/// <param name="e">				Event information. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void ScriptLocalFind(this UserControl control, object sender, EventArgs e) {
			JS.ScriptFind(sender as Control);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A UserControl extension method that script local find. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="control">	The control to act on. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void ScriptLocalFind(this Control control) {
			JS.ScriptFind(control);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A Control extension method that script local get. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="control">	The control to act on. </param>
		/// <param name="sender">		Source of the event. </param>
		/// <param name="e">				Event information. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void ScriptLocalGet(this Page control, object sender, EventArgs e) {
			JS.ScriptGet(sender as Control);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A UserControl extension method that script local find. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="control">	The control to act on. </param>
		/// <param name="sender">		Source of the event. </param>
		/// <param name="e">				Event information. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void ScriptLocalFind(this Page control, object sender, EventArgs e) {
			JS.ScriptFind(sender as Control);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A Control extension method that appends a style. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="control">		The control to act on. </param>
		/// <param name="attributes">	The attributes. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void AppendStyle(this Control control, AttributeCollection attributes) {
			var style = attributes["style"] + "";
			if (style != "") AppendStyle(control, style);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A Control extension method that appends a style. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <exception cref="NotSupportedException">	Thrown when the requested operation is not supported. </exception>
		///
		/// <param name="control">	The control to act on. </param>
		/// <param name="style">		The style. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void AppendStyle(this Control control, string style) {
			WebControl wc = control as WebControl;
			if (wc != null) { wc.Style.Value += ";" +style; return; }
			HtmlControl hc = control as HtmlControl;
			if (hc != null) { hc.Style.Value += ";" + style; return; }
			throw new NotSupportedException(control.GetType() + " control type is not supported for CSS Style updates.");
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A Control extension method that appends the css class. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <exception cref="NotSupportedException">	Thrown when the requested operation is not supported. </exception>
		///
		/// <param name="control">	The control to act on. </param>
		/// <param name="cssClass">	The css class. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void AppendCssClass(this Control control, string cssClass) {
			if (cssClass + "" == "") return;
			WebControl wc = control as WebControl;
			if (wc != null) { wc.CssClass += " " + cssClass; return; }
			HtmlControl hc = control as HtmlControl;
			if (hc != null) { hc.Attributes["class"] += " " + cssClass; return; }
			throw new NotSupportedException(control.GetType() + " control type is not supported for CSS Class updates.");
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A DataGrid extension method that converts this object to an excel. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="dg">		The dg to act on. </param>
		/// <param name="page">	The page. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void ToExcel(this DataGrid dg, Page page) {
			dg.ToExcel(page, "");
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A DataGrid extension method that converts this object to an excel. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="dg">				The dg to act on. </param>
		/// <param name="page">			The page. </param>
		/// <param name="fileName">	Filename of the file. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static void ToExcel(this DataGrid dg,Page page, string fileName) {
			Page m_pPage = page ?? new Page();
			System.Web.HttpContext context = System.Web.HttpContext.Current;
			//export to excel
			Action<Control> ClearControls = null;
			ClearControls = new Action<Control>((control) => {
				for (int i = control.Controls.Count - 1; i >= 0; i--) {
					ClearControls(control.Controls[i]);
				}

				if (!(control is DataGrid) && !(control is TableCell)) {
					if (control.GetType().GetProperty("SelectedItem") != null) {
						LiteralControl literal = new LiteralControl();
						control.Parent.Controls.Add(literal);
						try {
							literal.Text = (string)control.GetType().GetProperty("SelectedItem").GetValue(control, null);
						} catch {

						}

						control.Parent.Controls.Remove(control);
					} else

						if (control.GetType().GetProperty("Text") != null) {
							LiteralControl literal = new LiteralControl();
							control.Parent.Controls.Add(literal);
							literal.Text = (string)control.GetType().GetProperty("Text").GetValue(control, null);
							control.Parent.Controls.Remove(control);
						}
				}
				return;
			});

			context.Response.Clear();
			context.Response.Buffer = true;
			context.Response.ContentType = "application/vnd.ms-excel";
			if (fileName + "" != "") context.Response.AddHeader("content-disposition", "attachment; filename=" + fileName + ".xls");
			context.Response.Charset = "";
			m_pPage.EnableViewState = false;

			System.IO.StringWriter oStringWriter = new System.IO.StringWriter();
			System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);

			ClearControls(dg);
			dg.RenderControl(oHtmlTextWriter);

			context.Response.Write(oStringWriter.ToString());

			context.Response.End();
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Summary description for ExportToExcel. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public class ExportToExcel {
			private Page m_pPage = null;
			public ExportToExcel(Page pPage) {
				m_pPage = pPage;
			}

			public void ExportDataGrid(System.Web.UI.WebControls.DataGrid dg) {
				System.Web.HttpContext context = System.Web.HttpContext.Current;
				//export to excel

				context.Response.Clear();
				context.Response.Buffer = true;
				context.Response.ContentType = "application/vnd.ms-excel";
				context.Response.Charset = "";
				m_pPage.EnableViewState = false;

				System.IO.StringWriter oStringWriter = new System.IO.StringWriter();
				System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);

				this.ClearControls(dg);
				dg.RenderControl(oHtmlTextWriter);

				context.Response.Write(oStringWriter.ToString());

				context.Response.End();
			}

			private void ClearControls(Control control) {
				for (int i = control.Controls.Count - 1; i >= 0; i--) {
					ClearControls(control.Controls[i]);
				}

				if (!(control is TableCell)) {
					if (control.GetType().GetProperty("SelectedItem") != null) {
						LiteralControl literal = new LiteralControl();
						control.Parent.Controls.Add(literal);
						try {
							literal.Text = (string)control.GetType().GetProperty("SelectedItem").GetValue(control, null);
						} catch {

						}

						control.Parent.Controls.Remove(control);
					} else

						if (control.GetType().GetProperty("Text") != null) {
							LiteralControl literal = new LiteralControl();
							control.Parent.Controls.Add(literal);
							literal.Text = (string)control.GetType().GetProperty("Text").GetValue(control, null);
							control.Parent.Controls.Remove(control);
						}
				}
				return;
			}

		}

	}
}
